use askama_axum::{IntoResponse, Template};
use axum::extract::State;
use axum::Form;
use axum::response::Redirect;
use tower_sessions::Session;
use crate::core::pwd::get_password;
use crate::core::AppState;
use crate::services::backend::admin_service::AdminService;
use crate::types::backend::auth_type::LoginForm;

use super::AdminSession;


#[derive(Template)]
#[template(path = "backend/login.html")]
struct LoginFormTemplate;


pub async fn login_handler() -> impl IntoResponse {
    let template = LoginFormTemplate {};
    return axum::response::Html(template.render().unwrap());
}

pub async fn login_in_handler(
    State(state): State<AppState>,
    session: Session, 
    Form(form): Form<LoginForm>) -> Redirect {
    let admin_res = AdminService::get_admin_by_name(&state.db, &form.name).await;
    let admin = match admin_res {
        Ok(data) => data,
        Err(_) => {
            return Redirect::to("/backend/login")
        }
    };
    let pwd = get_password(&form.password);
    if admin.password != pwd {
        return Redirect::to("/backend/login")
    }
    let admin_session = AdminSession{
        id: admin.id,
        username: admin.name
    };
    let res = session.insert("admin", admin_session).await;
    match res {
        Ok(_) => {
            let new_login_count = admin.login_count + 1;
            let _ = AdminService::update_admin_login(&state.db, admin.id, new_login_count).await;
            return Redirect::to("/backend/dashboard")
        },
        Err(_) => {
            return Redirect::to("/backend/login")
        },
    }
}

pub async fn logout_handler(session: Session) -> Redirect {
    let res = session.remove_value("admin").await;
    match res {
        Ok(_) => {
            return Redirect::to("/backend/login")
        },
        Err(_) => {
            return Redirect::to("/backend/login")
        },
    }
}